#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "huffman.h"



char chs[MAX_CHAR];
int ws[MAX_CHAR];
int n = 0;

void loadDataFromFile(const char *filename) {
    FILE *fp = fopen(filename, "r");
    if (!fp) {
        printf("无法打开文件 %s\n", filename);
        return;
    }
    n = 0;
    char buf[64];
    while (fscanf(fp, "%s", buf) == 1) {
        if (strcmp(buf, "空格") == 0) chs[n] = ' ';
        else chs[n] = buf[0];
        fscanf(fp, "%d", &ws[n]);
        n++;
    }
    fclose(fp);
    printf("已读取 %d 个字符及权值。\n", n);
}

void inputData() {
    printf("请输入字符集大小 n：");
    scanf("%d", &n);
    printf("请输入 %d 个字符及其权值（如 A 64）：\n", n);
    for (int i = 0; i < n; ++i) {
        char buf[16];
        scanf("%s", buf);
        if (strcmp(buf, "空格") == 0) chs[i] = ' ';
        else chs[i] = buf[0];
        scanf("%d", &ws[i]);
    }
}

void printCodeTable(CodeTable table[], int n) {
    printf("字符\t权值\t哈夫曼编码\n");
    for (int i = 0; i < n; ++i) {
        if (table[i].ch == ' ') printf("空格\t");
        else printf("%c\t", table[i].ch);
        printf("%d\t%s\n", ws[i], table[i].code);
    }
}

int main() {
    #ifdef _WIN32
    system("chcp 65001"); // 切换终端为UTF-8
    #endif
    
    int mode = 0; // 0-未选，1-动态，2-静态
    DTree droot = NULL;
    STree stree;
    int sroot = -1;
    CodeTable table[MAX_CHAR];

    while (1) {
        printf("\n====== 哈夫曼编码/译码系统 ======\n");
        printf("1. 从文件读取权值数据\n");
        printf("2. 手动输入权值数据\n");
        printf("3. 选择存储结构（1-动态 2-静态）\n");
        printf("4. 构建哈夫曼树\n");
        printf("5. 显示哈夫曼树\n");
        printf("6. 哈夫曼编码\n");
        printf("7. 哈夫曼译码\n");
        printf("0. 退出\n");
        printf("请选择操作：");
        int op;
        scanf("%d", &op);
        if (op == 0) break;
        if (op == 1) loadDataFromFile("data.txt");
        else if (op == 2) inputData();
        else if (op == 3) {
            printf("请选择存储结构（1-动态 2-静态）：");
            scanf("%d", &mode);
        }
        else if (op == 4) {
            if (n == 0) { printf("请先输入或读取数据！\n"); continue; }
            if (mode == 1) {
                if (droot) freeDTree(droot);
                droot = buildDTree(chs, ws, n);
                printf("动态哈夫曼树已构建。\n");
            } else if (mode == 2) {
                sroot = buildSTree(chs, ws, n, stree);
                printf("静态哈夫曼树已构建。\n");
            } else {
                printf("请先选择存储结构！\n");
            }
        }
        else if (op == 5) {
            if (mode == 1 && droot) printDTree(droot, 0);
            else if (mode == 2 && sroot != -1) printSTree(stree, n, sroot, 0);
            else printf("请先构建哈夫曼树！\n");
        }
        else if (op == 6) {
            if (mode == 1 && droot) {
                getDCodes(droot, table, n);
                printCodeTable(table, n);
                char str[256], res[1024];
                printf("请输入要编码的字符串：");
                scanf(" %[^\n]", str);
                encodeD(droot, str, res);
                printf("编码结果：%s\n", res);
            } else if (mode == 2 && sroot != -1) {
                getSCodes(stree, n, table);
                printCodeTable(table, n);
                char str[256], res[1024];
                printf("请输入要编码的字符串：");
                scanf(" %[^\n]", str);
                encodeS(stree, n, str, res);
                printf("编码结果：%s\n", res);
            } else {
                printf("请先构建哈夫曼树！\n");
            }
        }
        else if (op == 7) {
            char code[1024], res[256];
            printf("请输入要译码的哈夫曼编码串：");
            scanf(" %s", code);
            if (mode == 1 && droot) {
                decodeD(droot, code, res);
                printf("译码结果：%s\n", res);
            } else if (mode == 2 && sroot != -1) {
                decodeS(stree, n, code, res);
                printf("译码结果：%s\n", res);
            } else {
                printf("请先构建哈夫曼树！\n");
            }
        }
        else printf("无效操作！\n");
    }
    if (droot) freeDTree(droot);
    printf("程序已退出。\n");
    return 0;
}